#coding:utf-8
__author__ = 'zhanglong'

import rsa
from alipay_py import alipay_config
import base64

SIGN_TYPE = "SHA-256"
import urllib
import requests
import hashlib
import urllib.parse

def params_filter(params):
    """
    去掉不需要验证前面的参数
    :param params:
    :return:
    """
    """
    :param params:
    :return:
    """
    ret = {}
    for key, value in params.items():
        if key == "sign" or value == "":#sign_type need include to sign now
            continue
        ret[key] = value
    return ret

def params_escape(dict):
    escapedDict = {}
    for key, value in dict.items():
        str = urllib.quote_plus(value)
        escapedDict[key] = str
    return escapedDict

def query_to_dict(query):
    """
    将query string转换成字典
    :param query:
    :return:
    """
    res = {}
    k_v_pairs = query.split("&")
    for item in k_v_pairs:
        sp_item = item.split("=", 1)  #注意这里，因为sign秘钥里面肯那个包含'='符号，所以splint一次就可以了
        key = sp_item[0]
        value = sp_item[1]
        res[key] = value

    return res


def params_to_query(params, quotes=False, reverse=False):
    """
        生成需要签名的字符串
    :param params:
    :return:
    """
    """
    :param params:
    :return:
    """
    query = ""
    for key in sorted(params.keys(), reverse=reverse):
        value = params[key]
        if quotes == True:
            query += str(key) + "=\"" + str(value) + "\"&"
        else:
            query += str(key) + "=" + str(value) + "&"
    query = query[0:-1]
    return query


def make_sign(message):
    """
    签名
    :param message:
    :return:
    """
    private_key = rsa.PrivateKey._load_pkcs1_pem(alipay_config.RSA_PRIVATE)
    sign = rsa.sign(message, private_key, SIGN_TYPE)
    b64sing = base64.b64encode(sign)
    return b64sing

def make_md5_sign(message):
    m = hashlib.md5()
    m.update(message)
    m.update(alipay_config.key)
    return m.hexdigest()


def check_sign(message, sign):
    """
    验证自签名
    :param message:
    :param sign:
    :return:
    """
    sign = base64.b64decode(sign)
    pubkey = rsa.PublicKey.load_pkcs1_openssl_pem(alipay_config.RSA_PUBLIC)
    return rsa.verify(message, sign, pubkey)


def check_ali_sign(message, sign):
    """
    验证ali签名
    :param message:
    :param sign:
    :return:
    """
    sign = base64.b64decode(sign)
    pubkey = rsa.PublicKey.load_pkcs1_openssl_pem(alipay_config.RSA_ALIPAY_PUBLIC)
    res = False
    try:
        res = rsa.verify(message, sign, pubkey)
    except Exception as e:
        print(e)
        res = False
    return res


def make_payment_request(params_dict):
    """
    构造一个支付请求的信息，包含最终结果里面包含签名
    :param params_dict:
    :return:
    """
    query_str = params_to_query(params_dict, quotes=True) #拼接签名字符串
    sign = make_sign(query_str) #生成签名
    res = "%s&sign=%s" % (query_str, sign)
    dict = query_to_dict(res)
    dict = params_escape(dict)
    res = params_to_query(dict)
    return res




def verify_alipay_request_sign(params_dict):
    """
    验证阿里支付回调接口签名
    :param params_dict: 阿里回调的参数列表
    :return:True or False
    """
    sign = params_dict['sign']
    params = params_filter(params_dict)
    message = params_to_query(params, quotes=False, reverse=False)
    check_res = check_ali_sign(message, sign)
    return check_res


def verify_from_gateway(params_dict):
    """
    从阿里网关验证请求是否正确
    :param params_dict:
    :return:
    """
    ali_gateway_url = "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=%(partner)d&notify_id=%(notify_id)s"
    notify_id = params_dict["notify_id"]
    partner = alipay_config.partner_id
    ali_gateway_url = ali_gateway_url % {"partner": partner, "notify_id": notify_id}
    res = requests.get(ali_gateway_url)
    #    res_dict = encoder.XML2Dict.parse(res.text)
    if res.text == "true":
        return True
    return False
